package com.system.ad.index.adunit;

import com.system.ad.index.IndexAware;
import com.system.ad.index.adplan.AdPlanVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 广告单元索引服务，实现了索引管理接口 IndexAware。
 */
@Slf4j
@Component
public class AdUnitIndex implements IndexAware<Long, AdUnitVo> {
    private static Map<Long, AdUnitVo> indexMap = new ConcurrentHashMap<>();

    /**
     * 根据广告位置类型匹配相应的广告单元ID集合。
     * @param positionType 广告位置类型
     * @return 匹配的广告单元ID集合
     */
    public Set<Long> match(Integer positionType) {

        Set<Long> adUnitIds = new HashSet<>();

        indexMap.forEach((k, v) -> {
            if (AdUnitVo.isAdSlotTypeOK(positionType, v.getPositionType())) {
                adUnitIds.add(k);
            }
        });

        return adUnitIds;
    }

    /**
     * 根据广告单元ID集合获取广告单元信息列表。
     * @param adUnitIds 广告单元ID集合
     * @return 广告单元信息列表
     */
    public List<AdUnitVo> fetch(Collection<Long> adUnitIds) {

        if (CollectionUtils.isEmpty(adUnitIds)) {
            return Collections.emptyList();
        }

        List<AdUnitVo> result = new ArrayList<>();

        adUnitIds.forEach(u -> {
            AdUnitVo object = get(u);
            if (object == null) {
                log.error("AdUnitObject not found: {}", u);
                return;
            }
            result.add(object);
        });

        return result;
    }

    @Override
    public AdUnitVo get(Long key) {
        return indexMap.get(key);
    }

    @Override
    public void add(Long key, AdUnitVo value) {
        log.info("before add:{}", indexMap);
        indexMap.put(key, value);
        log.info("after add:{}", indexMap);
    }

    @Override
    public void update(Long key, AdUnitVo value) {
        log.info("before update:{}", indexMap);
        AdUnitVo adUnitVo = indexMap.get(key);
        if (adUnitVo == null) {
            indexMap.put(key, value);
        } else {
            adUnitVo.update(value);
        }
        log.info("after update:{}", indexMap);
    }

    @Override
    public void delete(Long key, AdUnitVo value) {
        log.info("before delete:{}", indexMap);
        indexMap.remove(key);
        log.info("after delete:{}", indexMap);
    }
}
